﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Storage;
using System.IO;
using System.Xml.Serialization;

namespace space_scavenger
{
    public class InputState
    {

        public static class Commands
        {
            public const string
            MOVE_UP_COMMAND = "MoveUp",
            MOVE_DOWN_COMMAND = "MoveDown",
            MOVE_LEFT_COMMAND = "MoveLeft",
            MOVE_RIGHT_COMMAND = "MoveRight",
            FIRE_COMMAND = "Fire",
            __DEBUG__SAVE_KEYS = "__DEBUG__SaveKeys",
            EXIT = "Exit";

            public static string[] ALL_COMMANDS = {
                MOVE_UP_COMMAND,
                MOVE_DOWN_COMMAND,
                MOVE_LEFT_COMMAND,
                MOVE_RIGHT_COMMAND,
                FIRE_COMMAND,
                __DEBUG__SAVE_KEYS,
                EXIT
            };
        }

        private bool hasChanged;
        //private StorageDevice storageDevice;


        public bool HasChanged
        {
            get { return hasChanged; }
            set { hasChanged = value; }
        }

       /* public StorageDevice StorageDevice
        {
            get { return storageDevice; }
            set { storageDevice = value; }
        }*/

        private KeyboardState keystate;
        private GamePadState padstate;
        private Dictionary<string, List<Keys>> keyMapping;
        //Dictionary GamePadMapping

        private static InputState inst;

        private InputState()
        {
            //Config Keyboard/Gamepad states for left/right/up/down/button1...
            //placeholder
            keyMapping = new Dictionary<string, List<Keys>>(){
                {Commands.MOVE_UP_COMMAND, new List<Keys>(){Keys.Up, Keys.W,}},
                {Commands.MOVE_DOWN_COMMAND, new List<Keys>(){Keys.Down, Keys.S}},
                {Commands.MOVE_LEFT_COMMAND, new List<Keys>(){Keys.Left, Keys.A}},
                {Commands.MOVE_RIGHT_COMMAND, new List<Keys>(){Keys.Right, Keys.D}},
                {Commands.FIRE_COMMAND, new List<Keys>(){Keys.Space, Keys.LeftControl}},
                {Commands.__DEBUG__SAVE_KEYS, new List<Keys>(){Keys.F1}},
                {Commands.EXIT, new List<Keys>(){Keys.Escape}}
            };
            HasChanged = true;
        }

        public static InputState getInstance()
        {
            if (inst == null)
            {
                inst = new InputState();
            }
            return inst;
        }

        public void Update(GameTime gameTime)
        {
            if (HasChanged /*&& StorageDevice != null*/)
            {
                loadConfig();
                HasChanged = false;
            }

            keystate = Keyboard.GetState();
            padstate = GamePad.GetState(PlayerIndex.One);
        }

        public bool checkCommand(string command)
        {
            if (keyMapping.ContainsKey(command))
            {
                List<Keys> keysToCheck = keyMapping[command];
                foreach (Keys k in keysToCheck)
                {
                    if (keystate.IsKeyDown(k)) return true;
                }
            }
            return false;
        }

        public void loadConfig()
        {
            /*if (StorageDevice != null && StorageDevice.IsConnected)
            {
                StorageContainer container = StorageDevice.OpenContainer("config");
            */
                string filename = Path.Combine(StorageContainer.TitleLocation, "key.cfg");
                System.Console.Out.WriteLine("Loading key config from: " + filename);
                if (File.Exists(filename))
                {
                    keyMapping.Clear();
                    FileStream stream = File.Open(filename, FileMode.Open, FileAccess.Read);

                    /*XmlSerializer serializer = new XmlSerializer(typeof(Dictionary<string, List<Keys>>),
                        new Type[] { typeof(string), typeof(List<Keys>), typeof(Keys) });
                    keyMapping = (Dictionary<string, List<Keys>>)serializer.Deserialize(stream);
                    
                    */
                    StreamReader reader = new StreamReader(stream);
                    string line = reader.ReadLine();
                    while (line != null)
                    {
                        string[] keyValue = line.Split('=');
                        if (keyValue.Length != 2)
                        {
                            System.Console.Out.WriteLine("Line may be malformed");
                        }
                        string[] keys = keyValue[1].Split(',');
                        List<Keys> list = new List<Keys>();
                        foreach (string k in keys)
                        {
                            list.Add((Keys)Enum.Parse(typeof(Keys), k));
                        }
                        keyMapping.Add(keyValue[0], list);

                        line = reader.ReadLine();
                    }
                    reader.Close();
                    //stream.Close();
                }
              /*  container.Dispose();
            }*/
        }

        public void saveConfig()
        {
            string filename = Path.Combine(StorageContainer.TitleLocation, "key.cfg");
            System.Console.Out.WriteLine("Saving key config to: " + filename);
            FileStream stream = File.Open(filename, FileMode.Create);
            
            /*XmlSerializer serializer = new XmlSerializer(typeof(Dictionary<string, List<Keys>>),
                new Type[] { typeof(string), typeof(List<Keys>), typeof(Keys) });
            serializer.Serialize(stream, keyMapping);

            */
            StreamWriter writer = new StreamWriter(stream);
            foreach(KeyValuePair<string,List<Keys>> entry in keyMapping){
                writer.Write(entry.Key);
                writer.Write("=");
                Keys[] keys = entry.Value.ToArray();
                Keys last = keys.Last<Keys>();
                foreach (Keys k in keys)
                {
                    writer.Write(k);
                    if (last != k)
                    {
                        writer.Write(",");
                    }
                    
                }

                writer.Write(writer.NewLine);

            }
            writer.Flush();
            writer.Close();
            //stream.Close();
        }
    }
}
